package com.ithuameng.admin.app.system.controller;

import com.ithuameng.admin.app.system.model.Menu;
import com.ithuameng.admin.app.system.model.User;
import com.ithuameng.admin.app.system.model.admin.vo.AdminInfoVo;
import com.ithuameng.admin.app.system.model.admin.vo.AdminLoginVo;
import com.ithuameng.admin.app.system.model.admin.vo.RouterVo;
import com.ithuameng.admin.app.system.model.admin.vo.UserNoPwdVo;
import com.ithuameng.admin.app.system.model.vo.R;
import com.ithuameng.admin.app.system.service.IMenuService;
import com.ithuameng.admin.app.system.service.IPermissionService;
import com.ithuameng.admin.app.system.service.IUserService;
import com.ithuameng.admin.constants.CommonConstants;
import com.ithuameng.admin.enums.CommonError;
import com.ithuameng.admin.enums.YesNo;
import com.ithuameng.admin.security.JwtTokenProvider;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 账户相关
 *
 * @author ithuameng
 */
@Api(tags = "账户控制器")
@RestController
@RequestMapping(value = "/admin/v1/account")
public class AccountController extends AdminBaseController {

    @Resource
    private JwtTokenProvider jwtTokenProvider;

    @Resource
    private IUserService userService;

    @Resource
    private IMenuService menuService;

    @Resource
    private IPermissionService permissionService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @ApiOperation("登录")
    @PostMapping("/login")
    public R<String> login(@Valid @RequestBody AdminLoginVo loginVo) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        User user = userService.getUserByUsername(loginVo.getUsername().toLowerCase());
        if (user == null) {
            return new R<>(CommonError.BIZ_ERR, "用户名不存在");
        }
        if (!passwordEncoder.matches(loginVo.getPassword(), user.getPassword())) {
            return new R<>(CommonError.BIZ_ERR, "用户名或者密码错误");
        }
        if (YesNo.YES != user.getStatus()) {
            return new R<>(CommonError.BIZ_ERR, "账户已被禁用,请联系管理员");
        }
        String userToken = UUID.randomUUID().toString().replace("-", "");
        Map<String, String> attributes = new HashMap<>();
        attributes.put(CommonConstants.USER_ID, user.getId().toString());
        attributes.put(CommonConstants.USER_NAME, user.getUsername());
        attributes.put(CommonConstants.USER_TOKEN, userToken);
        // 注意这里最好和JWT TOKEN保持一致
        redisTemplate.opsForValue().set(CommonConstants.REIDS_KEY_PWY_TOKEN + user.getId().toString(), userToken,
                JwtTokenProvider.TOKEN_VALID_MILLISECONDS, TimeUnit.MILLISECONDS);
        String token = jwtTokenProvider.createToken(attributes);
        return new R<>(token);
    }

    @ApiOperation("退出登录")
    @PostMapping("/logout")
    public R<String> logout() {
        return new R<>(CommonError.OK, "退出登录成功");
    }

    @ApiOperation("获取用户信息")
    @GetMapping("/getInfo")
    public R<AdminInfoVo> getInfo(HttpServletRequest request) {
        Long userId = super.getLoginUserId(request);
        User user = userService.getById(userId);
        if (user == null) {
            return new R<>(CommonError.BIZ_ERR, "获取用户信息失败");
        }
        UserNoPwdVo userNoPwdVo = new UserNoPwdVo();
        BeanUtils.copyProperties(user, userNoPwdVo);
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(userId);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(userId);
        AdminInfoVo adminInfoVo = new AdminInfoVo();
        adminInfoVo.setUser(userNoPwdVo);
        adminInfoVo.setPermissions(permissions);
        adminInfoVo.setRoles(roles);
        return new R<>(adminInfoVo);
    }

    @ApiOperation("获取路由信息")
    @GetMapping("getRouters")
    public R<List<RouterVo>> getRouters(HttpServletRequest request) {
        Long userId = super.getLoginUserId(request);
        List<Menu> menus = menuService.selectMenuTreeByUserId(userId);
        return new R<>(menuService.buildMenus(menus));
    }
}
